home *** CD-ROM | disk | FTP | other *** search
/ Multimedia Jumpstart / Multimedia Microsoft Jumpstart Version 1.1a (Microsoft).BIN / develpmt / sdk / vfw11.win / vfwdk / puzzle.c_ / puzzle.bin
Encoding:
Text File  |  1993-11-19  |  3.9 KB  |  154 lines

  1. /**************************************************************************
  2.  *
  3.  *  THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
  4.  *  KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
  5.  *  IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
  6.  *  PURPOSE.
  7.  *
  8.  *  Copyright (c) 1992, 1993  Microsoft Corporation.  All Rights Reserved.
  9.  * 
  10.  **************************************************************************/
  11.  
  12. #include <windows.h>
  13. #include <mmsystem.h>
  14. #include <stdlib.h>
  15. #include "puzzle.h"
  16.  
  17. // C7 _fmemset does not work, it wants near pointer?
  18. char achHack[1024] = {0};
  19.  
  20. //
  21. // Initialize the puzzle, and optionally simulate 1000 clicks on the puzzle
  22. //
  23. void InitPuzzle(LPPUZZLE p, BOOL fScramble)
  24. {
  25.     int i,j;
  26.  
  27.     // Set the puzzle to a "solved" state
  28.     for (i = 0; i < PSIZE; i++)
  29.     for (j = 0; j < PSIZE; j++)
  30.         p->a[i][j] = i + j * PSIZE;
  31.  
  32.     // Put the "hole" in the lower right corner.
  33.     p->a[PSIZE-1][PSIZE-1] = -1;
  34.     p->hx = PSIZE - 1;
  35.     p->hy = PSIZE - 1;
  36.  
  37.     if (fScramble) {
  38.     // Make things really be random
  39.     srand((unsigned int) timeGetTime());
  40.     
  41.     for (i = 0; i < 1000; i++) {
  42.         int r, s;
  43.  
  44.         // Click on a random square
  45.         r = rand() % PSIZE;
  46.         s = rand() % PSIZE;
  47.  
  48.         ClickPuzzle(p, r, s);
  49.     }
  50.     }
  51. }
  52.  
  53. //
  54. // Given a puzzle, and x & y in puzzle coordinates, move squares around
  55. // or not as appropriate, given how such puzzles work.
  56. //
  57. void ClickPuzzle(LPPUZZLE p, int x, int y)
  58. {
  59.     int i;
  60.  
  61.     if (x < 0 || x >= PSIZE)
  62.     return;
  63.     
  64.     if (y < 0 || y >= PSIZE)
  65.     return;
  66.     
  67.     if (x == p->hx) {
  68.     if (y < p->hy) {
  69.         for (i = p->hy; i > y; i--) {
  70.         p->a[x][i] = p->a[x][i-1];
  71.         }
  72.     } else if (y > p->hy) {
  73.         for (i = p->hy; i < y; i++) {
  74.         p->a[x][i] = p->a[x][i+1];
  75.         }
  76.     }
  77.     p->hy = y;
  78.     p->a[x][y] = -1;
  79.     } else if (y == p->hy) {
  80.     if (x < p->hx) {
  81.         for (i = p->hx; i > x; i--) {
  82.         p->a[i][y] = p->a[i-1][y];
  83.         }
  84.     } else if (x > p->hx) {
  85.         for (i = p->hx; i < x; i++) {
  86.         p->a[i][y] = p->a[i+1][y];
  87.         }
  88.     }
  89.     p->hx = x;
  90.     p->a[x][y] = -1;
  91.     }
  92.  
  93.     // We could potentially see if the puzzle was solved here.
  94.     // If we do that, the prototype should change to
  95.     // BOOL ClickPuzzle(LPPUZZLE p, int x, int y, BOOL fCheckSolved)
  96.     // where we would pass TRUE for fCheckSolved if the call was
  97.     // a result of the user really clicking, and not a call from
  98.     // InitPuzzle() or something....
  99. }
  100.  
  101. #define WIDTHBYTES(i)     ((unsigned)((i+31)&(~31))/8)  /* ULONG aligned ! */
  102. #define DIBWIDTHBYTES(bi) (DWORD)WIDTHBYTES((int)(bi).biWidth * (int)(bi).biBitCount)
  103.  
  104. //
  105. // Given a puzzle, map the input picture to the output picture with squares
  106. // rearranged.
  107. //
  108. // Works on any RGB DIB.  Doesn't work on bitmaps, probably, so could be a
  109. // problem with Todd's new DrawDib.
  110. //
  111. void MixPicture(LPPUZZLE p, LPBITMAPINFOHEADER lpbi,
  112.         LPBYTE lpIn, LPBYTE lpOut)
  113. {
  114.     int     i,j;
  115.     LONG    lRowBytes;
  116.     int     y;
  117.     int     dx = ((int) lpbi->biWidth / PSIZE) * ((int) lpbi->biBitCount / 8);
  118.     int     dy = (int) lpbi->biHeight / PSIZE;
  119.     BYTE _huge *lpI;
  120.     BYTE _huge *lpO;
  121.     
  122.     lRowBytes = DIBWIDTHBYTES(*lpbi);
  123.  
  124.     for (i = 0; i < PSIZE; i++) {
  125.     for (j = 0; j < PSIZE; j++) {
  126.         // Get pointer to square we're copying into 
  127.         lpO = (BYTE _huge *) lpOut +
  128.           (PSIZE - 1 - j) * dy * lRowBytes +
  129.           dx * i;
  130.         
  131.         if (p->a[i][j] >= 0) {
  132.         // Get pointer to square we're copying from
  133.         lpI = (BYTE _huge *) lpIn +
  134.               (PSIZE - 1 - (p->a[i][j] / PSIZE)) * dy * lRowBytes +
  135.               dx * (p->a[i][j] % PSIZE);
  136.  
  137.         // do the copy
  138.         for (y = 0; y < dy; y++) {
  139.             hmemcpy(lpO, lpI, dx);
  140.             lpO += lRowBytes;
  141.             lpI += lRowBytes;
  142.         }
  143.         } else {
  144.         // clear the square to zeroes
  145.         for (y = 0; y < dy; y++) {
  146.             /////_fmemset(lpO, 0, dx);
  147.             hmemcpy(lpO, achHack, dx);
  148.             lpO += lRowBytes;
  149.         }
  150.         }
  151.     }
  152.     }
  153. }
  154.